/*
 * template_seesaw_2008b.c
 *
 * Real-Time Workshop code generation for Simulink model "template_seesaw_2008b.mdl".
 *
 * Model Version              : 1.37
 * Real-Time Workshop version : 7.2  (R2008b)  04-Aug-2008
 * C source code generated on : Fri Nov 18 14:24:38 2011
 */

#include "template_seesaw_2008b.h"
#include "template_seesaw_2008b_private.h"
#include <stdio.h>
#include "template_seesaw_2008b_dt.h"

/* options for Real-Time Windows Target board 0 */
static double RTWinBoardOptions0[] = {
  1.0,
  0.0,
  0.0,
};

/* list of Real-Time Windows Target boards */
const int RTWinBoardCount = 1;
RTWINBOARD RTWinBoards[1] = {
  { "National_Instruments/PCI-6014", 4294967295U, 3, RTWinBoardOptions0 },
};

/* Block signals (auto storage) */
BlockIO_template_seesaw_2008b template_seesaw_2008b_B;

/* Real-time model */
RT_MODEL_template_seesaw_2008b template_seesaw_2008b_M_;
RT_MODEL_template_seesaw_2008b *template_seesaw_2008b_M =
  &template_seesaw_2008b_M_;
static void rate_scheduler(void);

/*
 * This function updates active task flag for each subrate.
 * The function must be is called at model base rate, hence the
 * generated code self-manages all its subrates.
 */
static void rate_scheduler(void)
{
  /* Compute which subrates run during the next base time step.  Subrates
   * are an integer multiple of the base rate counter.  Therefore, the subtask
   * counter is reset when it reaches its limit (zero means run).
   */
  if (++template_seesaw_2008b_M->Timing.TaskCounters.TID[1] == 50) {/* Sample time: [0.25s, 0.0s] */
    template_seesaw_2008b_M->Timing.TaskCounters.TID[1] = 0;
  }

  template_seesaw_2008b_M->Timing.sampleHits[1] =
    (template_seesaw_2008b_M->Timing.TaskCounters.TID[1] == 0);
}

/* Model output function */
void template_seesaw_2008b_output(int_T tid)
{
  /* local block i/o variables */
  real_T rtb_AnalogInput[2];
  real_T rtb_Add1;

  {
    real_T rtb_Add2;

    /* Switch: '<S4>/SwitchControl' incorporates:
     *  Constant: '<Root>/Off'
     *  Constant: '<S4>/Constant'
     *  Saturate: '<Root>/Saturation -3.5 to 3.5v'
     */
    if (template_seesaw_2008b_P.Constant_Value >
        template_seesaw_2008b_P.SwitchControl_Threshold) {
      rtb_Add1 = rt_SATURATE(0.0,
        template_seesaw_2008b_P.Saturation35to35v_LowerSat,
        template_seesaw_2008b_P.Saturation35to35v_UpperSat);
    } else {
      rtb_Add1 = template_seesaw_2008b_P.Off_Value;
    }

    /* Gain: '<S2>/Gain' incorporates:
     *  Saturate: '<S2>/-5v to 5v'
     */
    rtb_Add1 = template_seesaw_2008b_P.Gain_Gain * rt_SATURATE(rtb_Add1,
      template_seesaw_2008b_P.uvto5v_LowerSat,
      template_seesaw_2008b_P.uvto5v_UpperSat);

    /* S-Function Block: <S2>/Analog Output */
    {
      {
        ANALOGIOPARM parm;
        parm.mode = (RANGEMODE) template_seesaw_2008b_P.AnalogOutput_RangeMode;
        parm.rangeidx = template_seesaw_2008b_P.AnalogOutput_VoltRange;
        RTBIO_DriverIO(0, ANALOGOUTPUT, IOWRITE, 1,
                       &template_seesaw_2008b_P.AnalogOutput_Channels, &rtb_Add1,
                       &parm);
      }
    }

    /* S-Function Block: <S1>/Analog Input */
    {
      ANALOGIOPARM parm;
      parm.mode = (RANGEMODE) template_seesaw_2008b_P.AnalogInput_RangeMode;
      parm.rangeidx = template_seesaw_2008b_P.AnalogInput_VoltRange;
      RTBIO_DriverIO(0, ANALOGINPUT, IOREAD, 2,
                     &template_seesaw_2008b_P.AnalogInput_Channels[0],
                     rtb_AnalogInput, &parm);
    }

    /* Sum: '<S1>/Add1' incorporates:
     *  Constant: '<S1>/Offset_theta (volt)'
     */
    rtb_Add1 = rtb_AnalogInput[1] +
      template_seesaw_2008b_P.Offset_thetavolt_Value;

    /* Sum: '<S1>/Add2' incorporates:
     *  Constant: '<S1>/Offset_x (volts)'
     */
    rtb_Add2 = template_seesaw_2008b_P.Offset_xvolts_Value + rtb_AnalogInput[0];
    if (template_seesaw_2008b_M->Timing.TaskCounters.TID[1] == 0) {
      /* RateTransition: '<S1>/Rate Transition' */
      template_seesaw_2008b_B.RateTransition[0] = rtb_Add2;
      template_seesaw_2008b_B.RateTransition[1] = rtb_Add1;

      /* RateTransition: '<S1>/Rate Transition1' incorporates:
       *  Gain: '<S1>/Convertion '
       *  Gain: '<S1>/Convertion actor'
       */
      template_seesaw_2008b_B.RateTransition1[0] =
        template_seesaw_2008b_P.Convertionactor_Gain * rtb_Add2;
      template_seesaw_2008b_B.RateTransition1[1] =
        template_seesaw_2008b_P.Convertion_Gain * rtb_Add1;

      /* Gain: '<S3>/Gain' */
      template_seesaw_2008b_B.Gain = template_seesaw_2008b_P.Gain_Gain_o *
        template_seesaw_2008b_B.RateTransition1[1];
    }
  }

  /* tid is required for a uniform function interface.
   * Argument tid is not used in the function. */
  UNUSED_PARAMETER(tid);
}

/* Model update function */
void template_seesaw_2008b_update(int_T tid)
{
  /* Update absolute time for base rate */
  if (!(++template_seesaw_2008b_M->Timing.clockTick0))
    ++template_seesaw_2008b_M->Timing.clockTickH0;
  template_seesaw_2008b_M->Timing.t[0] =
    template_seesaw_2008b_M->Timing.clockTick0 *
    template_seesaw_2008b_M->Timing.stepSize0 +
    template_seesaw_2008b_M->Timing.clockTickH0 *
    template_seesaw_2008b_M->Timing.stepSize0 * 4294967296.0;
  if (template_seesaw_2008b_M->Timing.TaskCounters.TID[1] == 0) {
    /* Update absolute timer for sample time: [0.25s, 0.0s] */
    if (!(++template_seesaw_2008b_M->Timing.clockTick1))
      ++template_seesaw_2008b_M->Timing.clockTickH1;
    template_seesaw_2008b_M->Timing.t[1] =
      template_seesaw_2008b_M->Timing.clockTick1 *
      template_seesaw_2008b_M->Timing.stepSize1 +
      template_seesaw_2008b_M->Timing.clockTickH1 *
      template_seesaw_2008b_M->Timing.stepSize1 * 4294967296.0;
  }

  rate_scheduler();

  /* tid is required for a uniform function interface.
   * Argument tid is not used in the function. */
  UNUSED_PARAMETER(tid);
}

/* Model initialize function */
void template_seesaw_2008b_initialize(boolean_T firstTime)
{
  (void)firstTime;

  /* Registration code */

  /* initialize non-finites */
  rt_InitInfAndNaN(sizeof(real_T));

  /* initialize real-time model */
  (void) memset((void *)template_seesaw_2008b_M,0,
                sizeof(RT_MODEL_template_seesaw_2008b));

  /* Initialize timing info */
  {
    int_T *mdlTsMap = template_seesaw_2008b_M->Timing.sampleTimeTaskIDArray;
    mdlTsMap[0] = 0;
    mdlTsMap[1] = 1;
    template_seesaw_2008b_M->Timing.sampleTimeTaskIDPtr = (&mdlTsMap[0]);
    template_seesaw_2008b_M->Timing.sampleTimes =
      (&template_seesaw_2008b_M->Timing.sampleTimesArray[0]);
    template_seesaw_2008b_M->Timing.offsetTimes =
      (&template_seesaw_2008b_M->Timing.offsetTimesArray[0]);

    /* task periods */
    template_seesaw_2008b_M->Timing.sampleTimes[0] = (0.005);
    template_seesaw_2008b_M->Timing.sampleTimes[1] = (0.25);

    /* task offsets */
    template_seesaw_2008b_M->Timing.offsetTimes[0] = (0.0);
    template_seesaw_2008b_M->Timing.offsetTimes[1] = (0.0);
  }

  rtmSetTPtr(template_seesaw_2008b_M, &template_seesaw_2008b_M->Timing.tArray[0]);

  {
    int_T *mdlSampleHits = template_seesaw_2008b_M->Timing.sampleHitArray;
    mdlSampleHits[0] = 1;
    mdlSampleHits[1] = 1;
    template_seesaw_2008b_M->Timing.sampleHits = (&mdlSampleHits[0]);
  }

  rtmSetTFinal(template_seesaw_2008b_M, -1);
  template_seesaw_2008b_M->Timing.stepSize0 = 0.005;
  template_seesaw_2008b_M->Timing.stepSize1 = 0.25;

  /* external mode info */
  template_seesaw_2008b_M->Sizes.checksums[0] = (176783285U);
  template_seesaw_2008b_M->Sizes.checksums[1] = (1462678525U);
  template_seesaw_2008b_M->Sizes.checksums[2] = (499234701U);
  template_seesaw_2008b_M->Sizes.checksums[3] = (2830249382U);

  {
    static const sysRanDType rtAlwaysEnabled = SUBSYS_RAN_BC_ENABLE;
    static RTWExtModeInfo rt_ExtModeInfo;
    static const sysRanDType *systemRan[3];
    template_seesaw_2008b_M->extModeInfo = (&rt_ExtModeInfo);
    rteiSetSubSystemActiveVectorAddresses(&rt_ExtModeInfo, systemRan);
    systemRan[0] = &rtAlwaysEnabled;
    systemRan[1] = &rtAlwaysEnabled;
    systemRan[2] = &rtAlwaysEnabled;
    rteiSetModelMappingInfoPtr(&rt_ExtModeInfo,
      &template_seesaw_2008b_M->SpecialInfo.mappingInfo);
    rteiSetChecksumsPtr(&rt_ExtModeInfo,
                        template_seesaw_2008b_M->Sizes.checksums);
    rteiSetTPtr(&rt_ExtModeInfo, rtmGetTPtr(template_seesaw_2008b_M));
  }

  template_seesaw_2008b_M->solverInfoPtr = (&template_seesaw_2008b_M->solverInfo);
  template_seesaw_2008b_M->Timing.stepSize = (0.005);
  rtsiSetFixedStepSize(&template_seesaw_2008b_M->solverInfo, 0.005);
  rtsiSetSolverMode(&template_seesaw_2008b_M->solverInfo,
                    SOLVER_MODE_SINGLETASKING);

  /* block I/O */
  template_seesaw_2008b_M->ModelData.blockIO = ((void *)
    &template_seesaw_2008b_B);
  (void) memset(((void *) &template_seesaw_2008b_B),0,
                sizeof(BlockIO_template_seesaw_2008b));

  /* parameters */
  template_seesaw_2008b_M->ModelData.defaultParam = ((real_T *)
    &template_seesaw_2008b_P);

  /* data type transition information */
  {
    static DataTypeTransInfo dtInfo;
    (void) memset((char_T *) &dtInfo,0,
                  sizeof(dtInfo));
    template_seesaw_2008b_M->SpecialInfo.mappingInfo = (&dtInfo);
    dtInfo.numDataTypes = 14;
    dtInfo.dataTypeSizes = &rtDataTypeSizes[0];
    dtInfo.dataTypeNames = &rtDataTypeNames[0];

    /* Block I/O transition table */
    dtInfo.B = &rtBTransTable;

    /* Parameters transition table */
    dtInfo.P = &rtPTransTable;
  }
}

/* Model terminate function */
void template_seesaw_2008b_terminate(void)
{
  /* S-Function Block: <S2>/Analog Output */
  {
    {
      ANALOGIOPARM parm;
      parm.mode = (RANGEMODE) template_seesaw_2008b_P.AnalogOutput_RangeMode;
      parm.rangeidx = template_seesaw_2008b_P.AnalogOutput_VoltRange;
      RTBIO_DriverIO(0, ANALOGOUTPUT, IOWRITE, 1,
                     &template_seesaw_2008b_P.AnalogOutput_Channels,
                     &template_seesaw_2008b_P.AnalogOutput_FinalValue, &parm);
    }
  }

  /* External mode */
  rtExtModeShutdown(2);
}

/*========================================================================*
 * Start of GRT compatible call interface                                 *
 *========================================================================*/
void MdlOutputs(int_T tid)
{
  template_seesaw_2008b_output(tid);
}

void MdlUpdate(int_T tid)
{
  template_seesaw_2008b_update(tid);
}

void MdlInitializeSizes(void)
{
  template_seesaw_2008b_M->Sizes.numContStates = (0);/* Number of continuous states */
  template_seesaw_2008b_M->Sizes.numY = (0);/* Number of model outputs */
  template_seesaw_2008b_M->Sizes.numU = (0);/* Number of model inputs */
  template_seesaw_2008b_M->Sizes.sysDirFeedThru = (0);/* The model is not direct feedthrough */
  template_seesaw_2008b_M->Sizes.numSampTimes = (2);/* Number of sample times */
  template_seesaw_2008b_M->Sizes.numBlocks = (23);/* Number of blocks */
  template_seesaw_2008b_M->Sizes.numBlockIO = (3);/* Number of block outputs */
  template_seesaw_2008b_M->Sizes.numBlockPrms = (22);/* Sum of parameter "widths" */
}

void MdlInitializeSampleTimes(void)
{
}

void MdlInitialize(void)
{
}

void MdlStart(void)
{
  /* S-Function Block: <S2>/Analog Output */
  {
    {
      ANALOGIOPARM parm;
      parm.mode = (RANGEMODE) template_seesaw_2008b_P.AnalogOutput_RangeMode;
      parm.rangeidx = template_seesaw_2008b_P.AnalogOutput_VoltRange;
      RTBIO_DriverIO(0, ANALOGOUTPUT, IOWRITE, 1,
                     &template_seesaw_2008b_P.AnalogOutput_Channels,
                     &template_seesaw_2008b_P.AnalogOutput_InitialValue, &parm);
    }
  }

  MdlInitialize();
}

RT_MODEL_template_seesaw_2008b *template_seesaw_2008b(void)
{
  template_seesaw_2008b_initialize(1);
  return template_seesaw_2008b_M;
}

void MdlTerminate(void)
{
  template_seesaw_2008b_terminate();
}

/*========================================================================*
 * End of GRT compatible call interface                                   *
 *========================================================================*/
